////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
//  File name:   ViewportTitleDlg.cpp
//  Version:     v1.00
//  Created:     15/9/2004 by Timur.
//  Compilers:   Visual Studio.NET
//  Description: CViewportTitleDlg implementation file
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ViewportTitleDlg.h"
#include "ViewPane.h"
#include "DisplaySettings.h"
#include "CustomResolutionDlg.h"
#include "AI/AIManager.h"

// CViewportTitleDlg dialog

IMPLEMENT_DYNAMIC(CViewportTitleDlg, CXTResizeDialog)

CViewportTitleDlg::CViewportTitleDlg(CWnd* pParent) 
	: CXTResizeDialog(CViewportTitleDlg::IDD, pParent),
	m_searchMode(ESM_BY_NAME), m_searchResultHandling(ESRH_HIDE_OTHERS),
	m_bOR(false),
	m_buttonTheme(NULL)
{
	m_pViewPane = NULL;
	GetIEditor()->RegisterNotifyListener(this);

	LoadCustomResPresets("ResPreset",m_customResPreset);
}

CViewportTitleDlg::~CViewportTitleDlg()
{
	CMDTARGET_RELEASE(m_buttonTheme);
	GetIEditor()->UnregisterNotifyListener(this);
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::SetViewPane( CLayoutViewPane *pViewPane )
{
	m_pViewPane = pViewPane;
};

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::SetThemeToButton( CXTPButtonTheme* pTheme, CColorCheckBox& button )
{	
	CMDTARGET_ADDREF( pTheme);
	pTheme->m_themeButton = CXTPWinThemeWrapper(FALSE);
	button.SetTheme(pTheme);
}

//////////////////////////////////////////////////////////////////////////
BOOL CViewportTitleDlg::OnInitDialog()
{
	CXTResizeDialog::OnInitDialog();
	// FR :commenting out the SetPushedBkColor since we changed the class of some buttons. Maybe to restore later
	m_maxBtn.SetIcon( MAKEINTRESOURCE(IDI_MAXIMIZE) );
	//m_maxBtn.SetPushedBkColor(::GetSysColor(COLOR_HIGHLIGHT));
	m_hideHelpersBtn.SetIcon( MAKEINTRESOURCE(IDI_HIDEHELPERS) );
//	m_titleBtn.SetIcon( MAKEINTRESOURCE(IDI_DOWN_ARROW),BS_RIGHT,true );
	m_titleBtn.SetWindowText(m_title);
	m_sizeTextCtrl.SetWindowText( "" );
	m_hideHelpersBtn.SetToolTip("Hide helpers toggle");
	//m_hideHelpersBtn.SetPushedBkColor(::GetSysColor(COLOR_HIGHLIGHT));

	m_viewportSearch.SetBitmaps(IDB_VIEWPORTSEARCH_BACKGROUND_EMPTY,
															IDB_VIEWPORTSEARCH_BACKGROUND_FILLED);
	CRect rcEditArea(20,4,125,17);
	m_viewportSearch.SetEditArea(rcEditArea);
	CRect rcFirstButtonArea(4,3,19,18);
	m_viewportSearch.SetFirstButtonArea(rcFirstButtonArea);
	CRect rcSecondButtonArea(128,3,143,18);
	m_viewportSearch.SetSecondButtonArea(rcSecondButtonArea);
	m_viewportSearch.SetOwner(this);
	m_viewportSearch.SetButtonClickedMessageId(WM_USER_EDITWITHBUTTON_CLICKED);
	m_viewportSearch.SetFirstButtonExistsAlways(TRUE);
	m_viewportSearch.SetSecondButtonExistsAlways(FALSE);

	UpdateSearchOptionsText();

	SetResize( IDC_VIEWPORT_SEARCH_OPTIONS,SZ_HORREPOS(1) );
	SetResize( IDC_VIEWPORT_SEARCH,SZ_HORREPOS(1) );
	SetResize( IDC_SIZE_TEXT,SZ_HORREPOS(1) );
	SetResize( IDC_VIEWPORT_MAXIMIZE,SZ_HORREPOS(1) );
	SetResize( IDC_VIEWPORT_HIDEHELPERS,SZ_HORREPOS(1) );

	m_brushGray.CreateSolidBrush(RGB(71,71,71));
	m_brushWhite.CreateSolidBrush(RGB(255,255,255));
	CBitmap bkBmp;
	bkBmp.LoadBitmap(IDB_VIEWPORTSEARCH_BACKGROUND_EMPTY);
	m_brushPattern.CreatePatternBrush(&bkBmp);

	m_buttonTheme = new CXTPButtonFlatTheme;
	SetThemeToButton(m_buttonTheme, m_maxBtn);
	SetThemeToButton(m_buttonTheme, m_hideHelpersBtn);

	return TRUE;
}

void CViewportTitleDlg::DoDataExchange(CDataExchange* pDX)
{
	CXTResizeDialog::DoDataExchange(pDX);
	DDX_Control(pDX,IDC_VIEWPORT_TITLE,m_titleBtn);
	DDX_Control(pDX,IDC_VIEWPORT_MAXIMIZE,m_maxBtn);
	DDX_Control(pDX,IDC_VIEWPORT_HIDEHELPERS,m_hideHelpersBtn);
	DDX_Control(pDX,IDC_SIZE_TEXT,m_sizeTextCtrl);
	DDX_Control(pDX,IDC_VIEWPORT_SEARCH,m_viewportSearch);
	DDX_Control(pDX,IDC_VIEWPORT_SEARCH_OPTIONS,m_searchOptionsText);
}


BEGIN_MESSAGE_MAP(CViewportTitleDlg, CXTResizeDialog)
	ON_BN_SETFOCUS(IDC_VIEWPORT_TITLE,OnButtonSetFocus)
	ON_BN_CLICKED(IDC_VIEWPORT_TITLE,OnTitle)
	//ON_CONTROL(BN_PUSHED,IDC_VIEWPORT_TITLE,OnTitle)
	ON_BN_CLICKED(IDC_VIEWPORT_MAXIMIZE,OnMaximize)
	ON_BN_CLICKED(IDC_VIEWPORT_HIDEHELPERS,OnHideHelpers)
	ON_WM_RBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_ERASEBKGND()
	ON_WM_CTLCOLOR()
	ON_WM_SIZE()
	ON_MESSAGE(WM_USER_EDITWITHBUTTON_CLICKED,OnViewportSearchButtonClicked)
	ON_EN_CHANGE(IDC_VIEWPORT_SEARCH,OnSearchTermChange )
END_MESSAGE_MAP()

// CViewportTitleDlg message handlers
//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::OnSetFocus( CWnd* )
{
	GetParent()->SetFocus();
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::SetTitle( const CString &title )
{
	m_title = title;
	if (m_titleBtn.m_hWnd)
		m_titleBtn.SetWindowText(m_title);
	if (title == "Perspective")
	{
		m_viewportSearch.ShowWindow(SW_SHOW);
		m_searchOptionsText.ShowWindow(SW_SHOW);
	}
	else
	{
		m_viewportSearch.ShowWindow(SW_HIDE);
		m_searchOptionsText.ShowWindow(SW_HIDE);
	}
}

//////////////////////////////////////////////////////////////////////////
HBRUSH CViewportTitleDlg::OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor )
{
	HBRUSH hbr = __super::OnCtlColor(pDC, pWnd, nCtlColor);

	if (nCtlColor == CTLCOLOR_STATIC
		|| nCtlColor == CTLCOLOR_BTN)
	{
		pDC->SetTextColor(RGB(240,240,240));
		pDC->SetBkMode(TRANSPARENT);
		return m_brushGray;
	}
	else if (nCtlColor == CTLCOLOR_EDIT)
	{
		pDC->SetTextColor(RGB(0,0,0));
		pDC->SetBkMode(TRANSPARENT);
		if (m_viewportSearch.GetWindowTextLength() > 0)
			return m_brushWhite;
		else
			return m_brushPattern;	// This is for showing the image of 'Ctrl+Shift+F'
															// as a background when the edit control is empty.
	}

	// TODO: Return a different brush if the default is not desired
	return hbr;
}

//////////////////////////////////////////////////////////////////////////
BOOL CViewportTitleDlg::OnEraseBkgnd(CDC* pDC) 
{
	////////////////////////////////////////////////////////////////////////
	// Erase the background of the window (only if no render has been
	// attached)
	////////////////////////////////////////////////////////////////////////

	RECT rect;
	CBrush cFillBrush;

	// Get the rect of the client window
	GetClientRect(&rect);

	XTPPaintManager()->GradientFill( pDC,&rect,RGB(71,71,71),RGB(71,71,71),FALSE );

	return TRUE;
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::OnButtonSetFocus()
{
	//GetParent()->SetFocus();
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	if (m_pViewPane)
		m_pViewPane->ToggleMaximize();
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::OnMaximize()
{
	//m_maxBtn.SetPushedBkColor(::GetSysColor(COLOR_HIGHLIGHT));
	if (m_pViewPane)
		m_pViewPane->ToggleMaximize();
	m_maxBtn.Invalidate();
}


//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::OnHideHelpers()
{
	//m_hideHelpersBtn.SetPushedBkColor(::GetSysColor(COLOR_HIGHLIGHT));
	GetIEditor()->GetDisplaySettings()->DisplayHelpers( !GetIEditor()->GetDisplaySettings()->IsDisplayHelpers());
	GetIEditor()->Notify(eNotify_OnDisplayRenderUpdate);

	if( GetIEditor()->GetDisplaySettings()->IsDisplayHelpers() == false )
		GetIEditor()->GetObjectManager()->SendEvent(EVENT_HIDE_HELPER);
}


//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
	if (m_pViewPane)
	{
		CRect rc;
		m_sizeTextCtrl.GetWindowRect(rc);
		ClientToScreen(&point);
		if (rc.PtInRect(point))
			PopUpResolutionMenu();
		else
			m_pViewPane->ShowTitleMenu();
	}
}


void CViewportTitleDlg::AddResolutionMenus(		CMenu& inMenu, 
												std::vector<CString>& inCustompreset,
												UINT_PTR inBaseID,
												UINT_PTR inCustomPresetBaseID, 
												UINT_PTR inCustomBaseID,
												std::vector< CRenderViewport::SResolution >& outResolutions )
{
	outResolutions.push_back( CRenderViewport::SResolution(1280, 720) );
	outResolutions.push_back( CRenderViewport::SResolution(1920, 1080) );
	outResolutions.push_back( CRenderViewport::SResolution(2560, 1440) );
	outResolutions.push_back( CRenderViewport::SResolution(2048, 858) );
	outResolutions.push_back( CRenderViewport::SResolution(1998, 1080) );

	for (size_t i=0; i<outResolutions.size(); ++i)
	{
		CString text;
		text.Format("%d x %d", outResolutions[i].width, outResolutions[i].height);
		inMenu.AppendMenu(MF_STRING,inBaseID+i, text);
	}

	inMenu.AppendMenu(MF_SEPARATOR, 0, "");

	// Then, add custom presets.
	for (size_t i=0; i<inCustompreset.size(); ++i)
	{
		if (inCustompreset[i].IsEmpty())
			break;
		inMenu.AppendMenu(MF_STRING, inCustomPresetBaseID+i, inCustompreset[i]);
	}

	inMenu.AppendMenu(MF_SEPARATOR, 0, "");

	// Add the entry for a custom resolution.
	inMenu.AppendMenu(MF_STRING, inCustomBaseID, "Custom...");
}


//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::PopUpResolutionMenu()
{
	if (m_pViewPane == NULL)
		return;

	std::vector< CRenderViewport::SResolution > presets;
	const UINT_PTR BASED_ID = 1;
	const UINT_PTR CUSTOM_PRSETS_BASE_ID = 50;
	const UINT_PTR CUSTOM_RES_MENU_ID = 100;

	CMenu resMenu;
	resMenu.CreatePopupMenu();

	// Add preset items.
	AddResolutionMenus( resMenu, m_customResPreset, BASED_ID, CUSTOM_PRSETS_BASE_ID, CUSTOM_RES_MENU_ID, presets );

	CPoint point;
	GetCursorPos(&point);

	// Show the popup menu.
	int id = resMenu.TrackPopupMenu(TPM_RETURNCMD|TPM_LEFTALIGN|TPM_LEFTBUTTON, point.x, point.y, this);
	
	// And process the result.
	if (id == CUSTOM_RES_MENU_ID)
	{
		CRect rcVP;
		m_pViewPane->GetViewport()->GetWindowRect(rcVP);
		CCustomResolutionDlg resDlg(rcVP.Width(), rcVP.Height(), this->GetParent());
		if (resDlg.DoModal() == IDOK)
		{
			m_pViewPane->ResizeViewport(resDlg.GetWidth(), resDlg.GetHeight());
			// Update the custom presets.
			CString text;
			text.Format("%d x %d", resDlg.GetWidth(), resDlg.GetHeight());
			UpdateCustomResPresets(text,m_customResPreset);
			SaveCustomResPresets("ResPreset",m_customResPreset);
		}
	}
	else if (id >= BASED_ID)
	{
		// Built-in presets
		if (id < CUSTOM_PRSETS_BASE_ID)
		{
			int index = id-BASED_ID;
			if ( index >= presets.size() )
				return;
			m_pViewPane->ResizeViewport(presets[index].width, presets[index].height);
		}
		// Custom presets
		else
		{
			int index = id - CUSTOM_PRSETS_BASE_ID;
			if (index >= MAX_NUM_CUSTOM_RES_PRESETS)
				return;
			if (m_customResPreset[index].IsEmpty())
				return;
			int width=0, height=0;
			if (sscanf(m_customResPreset[index], "%d x %d", &width, &height) == 2)
				m_pViewPane->ResizeViewport(width, height);
		}
	}
}


//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::OnTitle()
{
	if (m_pViewPane)
		m_pViewPane->ShowTitleMenu();
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::OnSize( UINT nType,int cx,int cy )
{
	CXTResizeDialog::OnSize(nType,cx,cy);
	if (m_maxBtn.m_hWnd)
	{
		CRect rc;
		//m_maxBtn.GetWindowRect(rc);
		//m_maxBtn.MoveWindow(0,cx-rc.Width(),rc.Width(),cy);
	}
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::SetViewportSize( int width,int height )
{
	if (m_sizeTextCtrl.m_hWnd)
	{
		CString str;
		str.Format( "%d x %d",width,height );
		m_sizeTextCtrl.SetWindowText( str );
	}
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::SetActive( bool bActive )
{
	
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::OnEditorNotifyEvent( EEditorNotifyEvent event )
{
	switch (event)
	{
	case eNotify_OnDisplayRenderUpdate:
		m_hideHelpersBtn.SetCheck(!GetIEditor()->GetDisplaySettings()->IsDisplayHelpers());
		break;
	}
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::InputNamesToSearchFromSelection()
{
	IObjectManager *pObjMgr = GetIEditor()->GetObjectManager();
	CSelectionGroup *pSelected = pObjMgr->GetSelection();
	string names;
	for(int i=0; i<pSelected->GetCount(); ++i)
	{
		names += pSelected->GetObject(i)->GetName();
		names += " ";
	}
	m_viewportSearch.SetWindowText(names.c_str());
}

//////////////////////////////////////////////////////////////////////////
LRESULT CViewportTitleDlg::OnViewportSearchButtonClicked(WPARAM wParam, LPARAM lParam)
{
	if(wParam == 0)				// Search options dropdown
	{
		const int SEARCH_BY_NAME = 1;
		const int SEARCH_BY_TYPE = 2;
		const int SEARCH_BY_ASSET = 3;

		const int HIDE_OTHERS = 4;
		const int	FREEZE_OTHERS = 5;
		const int	JUST_SELLECT = 6;

		const int LOGICAL_AND = 7;
		const int LOGICAL_OR = 8;

		const int INPUT_NAMES_FROM_SELECTION = 8;

		CMenu menu;
		menu.CreatePopupMenu();

		int flag = MF_STRING;
		flag = m_searchMode == ESM_BY_NAME ? (MF_STRING|MF_CHECKED) : MF_STRING;
		menu.AppendMenu(flag, SEARCH_BY_NAME, "By Name");
		flag = m_searchMode == ESM_BY_TYPE ? (MF_STRING|MF_CHECKED) : MF_STRING;
		menu.AppendMenu(flag, SEARCH_BY_TYPE, "By Type");
		flag = m_searchMode == ESM_BY_ASSET ? (MF_STRING|MF_CHECKED) : MF_STRING;
		menu.AppendMenu(flag, SEARCH_BY_ASSET, "By Asset");

		menu.AppendMenu(MF_SEPARATOR);
		
		flag = m_searchResultHandling == ESRH_HIDE_OTHERS 
						? (MF_STRING|MF_CHECKED)
						: MF_STRING;
		menu.AppendMenu(flag, HIDE_OTHERS, "Hide others");
		flag = m_searchResultHandling == ESRH_FREEZE_OTHERS
						? (MF_STRING|MF_CHECKED)
						: MF_STRING;
		menu.AppendMenu(flag, FREEZE_OTHERS, "Freeze others");
		flag = m_searchResultHandling == ESRH_JUST_SELECT
						? (MF_STRING|MF_CHECKED)
						: MF_STRING;		
		menu.AppendMenu(flag, JUST_SELLECT, "Just Select");
		
		menu.AppendMenu(MF_SEPARATOR);
		
		flag = m_bOR?MF_STRING:(MF_STRING|MF_CHECKED);
		menu.AppendMenu(flag, LOGICAL_AND, "AND");
		flag = m_bOR?(MF_STRING|MF_CHECKED):MF_STRING;
		menu.AppendMenu(flag, LOGICAL_OR, "OR");

		menu.AppendMenu(MF_SEPARATOR);

		menu.AppendMenu(MF_STRING, INPUT_NAMES_FROM_SELECTION, "Input names from selection");

		CRect rect;
		m_viewportSearch.GetWindowRect(&rect);
		int cmd = menu.TrackPopupMenu(TPM_RETURNCMD|TPM_LEFTALIGN|TPM_LEFTBUTTON, rect.left, rect.bottom, this);

#define ASSIGN(dst, src) do { if((dst) != (src)) { (dst) = (src); OnSearchTermChange(); }  } while(0)

		if(cmd == SEARCH_BY_NAME)
			ASSIGN(m_searchMode, ESM_BY_NAME);
		else if(cmd == SEARCH_BY_TYPE)
			ASSIGN(m_searchMode, ESM_BY_TYPE);
		else if(cmd == SEARCH_BY_ASSET)
			ASSIGN(m_searchMode, ESM_BY_ASSET);
		else if(cmd == HIDE_OTHERS)
			ASSIGN(m_searchResultHandling, ESRH_HIDE_OTHERS);
		else if(cmd == FREEZE_OTHERS)
			ASSIGN(m_searchResultHandling, ESRH_FREEZE_OTHERS);
		else if(cmd == JUST_SELLECT)
			ASSIGN(m_searchResultHandling, ESRH_JUST_SELECT);
		else if(cmd == LOGICAL_AND)
			ASSIGN(m_bOR, false);
		else if(cmd == LOGICAL_OR)
			ASSIGN(m_bOR, true);
		else if(cmd == INPUT_NAMES_FROM_SELECTION)
		{	
			InputNamesToSearchFromSelection();
			m_bOR = true;
			OnSearchTermChange();
		}

		UpdateSearchOptionsText();
	}
	else if(wParam == 1)	// Clear button
	{
		UnhideUnfreezeAll();
		//clear edit control
		m_viewportSearch.SetWindowText(_T(""));
		gSettings.bIsSearchFilterActive = false;
		GetIEditor()->GetAI()->RestartContinuousUpdate();
	}

	return 1;
}

void CViewportTitleDlg::OnCancel()
{
	GetParent()->SetFocus();
}


//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::SetFocusToSearchField()
{
	if(m_viewportSearch.IsWindowVisible())
	{
		m_viewportSearch.SetActiveWindow();
		m_viewportSearch.SetFocus();
	}
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::OnSearchTermChange()
{
	GetIEditor()->GetAI()->PauseContinousUpdate();

	// Get individual search terms.
	CString searchTerm;
	m_viewportSearch.GetWindowText(searchTerm);

	if(searchTerm.GetLength() > 0)
		gSettings.bIsSearchFilterActive = true;
	else
		gSettings.bIsSearchFilterActive = false;

	const int MIN_CHARS_AS_A_SEARCH_TERM = 3;
	std::vector<CString> terms;
	CString token;
	int curPos = 0;
	token = searchTerm.Tokenize(" ", curPos);
	while(token != "")
	{
		// For efficiency, don't take a too short word into consideration. 
		if(token.GetLength() >= MIN_CHARS_AS_A_SEARCH_TERM)
			terms.push_back(token.MakeLower());
		token = searchTerm.Tokenize(" ", curPos);
	}

	if(terms.empty())
	{
		UnhideUnfreezeAll();
		GetIEditor()->GetAI()->RestartContinuousUpdate();
		return;
	}

	// Perform a search.
	if(m_searchMode == ESM_BY_NAME)
		SearchByName(terms);
	else if(m_searchMode == ESM_BY_TYPE)
		SearchByType(terms);
	else if(m_searchMode == ESM_BY_ASSET)
		SearchByAsset(terms);
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::UnhideUnfreezeAll()
{
	IObjectManager *pObjMgr = GetIEditor()->GetObjectManager();
	int objCount = pObjMgr->GetObjectCount();
	CBaseObjectsArray objects;
	pObjMgr->GetObjects(objects);
	for(int i=0; i < objCount; ++i)
	{
		CBaseObject *pObject = objects[i];
		// Always abide by the layer state before unhiding or unfreezing.
		if(pObject->GetLayer()->IsFrozen() == false)
			pObjMgr->FreezeObject(pObject, false);
		if(pObject->GetLayer()->IsVisible() == true)
			pObjMgr->HideObject(pObject, false);
	}
}

//////////////////////////////////////////////////////////////////////////
static bool DoesTextSatisfyTerms(const CString& text, const std::vector<CString>& terms, bool bOR)
{
	if(bOR)			// OR
	{
		for(size_t i=0; i<terms.size(); ++i)
		{
			if(text.Find(terms[i]) != -1)
				return true;
		}
		return false;
	}
	else				// AND
	{
		for(size_t i=0; i<terms.size(); ++i)
		{
			if(text.Find(terms[i]) == -1)
				return false;
		}
		return true;
	}
}

//////////////////////////////////////////////////////////////////////////
static void HandleMatched(CBaseObject* pObject)
{
	IObjectManager *pObjMgr = GetIEditor()->GetObjectManager();

	if(pObject->GetLayer()->IsFrozen() == false)
		pObjMgr->FreezeObject(pObject, false);

	if(pObject->GetLayer()->IsVisible() == true)
		pObjMgr->HideObject(pObject, false);

	if(pObject->GetLayer()->IsFrozen() == false
	&& pObject->GetLayer()->IsVisible() == true)
		pObjMgr->SelectObject(pObject);
}

//////////////////////////////////////////////////////////////////////////
static void HandleFiltered(CBaseObject* pObject, CViewportTitleDlg::ESearchResultHandling searchResultHandling)
{
	IObjectManager *pObjMgr = GetIEditor()->GetObjectManager();
	pObjMgr->UnselectObject(pObject);
	if(searchResultHandling == CViewportTitleDlg::ESRH_HIDE_OTHERS)
	{
		if(pObject->GetLayer()->IsFrozen() == false)
			pObjMgr->FreezeObject(pObject, false);
		pObjMgr->HideObject(pObject, true);
	}
	else if(searchResultHandling == CViewportTitleDlg::ESRH_FREEZE_OTHERS)
	{
		if(pObject->GetLayer()->IsVisible() == true)
			pObjMgr->HideObject(pObject, false);
		pObjMgr->FreezeObject(pObject, true);
	}
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::SearchByType(const std::vector<CString>& terms)
{
	IObjectManager *pObjMgr = GetIEditor()->GetObjectManager();
	int objCount = pObjMgr->GetObjectCount();
	CBaseObjectsArray objects;
	pObjMgr->GetObjects(objects);
	for(int i=0; i < objCount; ++i)
	{
		CBaseObject *pObject = objects[i];
		CString type = pObject->GetTypeDescription();
		type.MakeLower();
		if(DoesTextSatisfyTerms(type, terms, m_bOR))
			HandleMatched(pObject);
		else
			HandleFiltered(pObject, m_searchResultHandling);
	}
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::SearchByName(const std::vector<CString>& terms)
{
	IObjectManager *pObjMgr = GetIEditor()->GetObjectManager();
	int objCount = pObjMgr->GetObjectCount();
	CBaseObjectsArray objects;
	pObjMgr->GetObjects(objects);
	for(int i=0; i < objCount; ++i)
	{
		CBaseObject *pObject = objects[i];
		CString name = pObject->GetName();
		name.MakeLower();
		if(DoesTextSatisfyTerms(name, terms, m_bOR))
			HandleMatched(pObject);
		else
			HandleFiltered(pObject, m_searchResultHandling);
	}
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::SearchByAsset(const std::vector<CString>& terms)
{
	IObjectManager *pObjMgr = GetIEditor()->GetObjectManager();
	int objCount = pObjMgr->GetObjectCount();
	CBaseObjectsArray objects;
	pObjMgr->GetObjects(objects);
	for(int i=0; i < objCount; ++i)
	{
		CBaseObject *pObject = objects[i];
		CUsedResources usedAssets;
		pObject->GatherUsedResources(usedAssets);
		CUsedResources::ResourceFiles::const_iterator itr = usedAssets.files.begin(), 
																									end = usedAssets.files.end();
		bool bMatch = false;
		for(; itr != end; ++itr)
		{
			CString filename = *itr;
			filename.MakeLower();
			if(DoesTextSatisfyTerms(filename, terms, m_bOR))
			{
				bMatch = true;
				break;
			}
		}
		if(bMatch)
			HandleMatched(pObject);
		else
			HandleFiltered(pObject, m_searchResultHandling);
	}
}

//////////////////////////////////////////////////////////////////////////
void CViewportTitleDlg::UpdateSearchOptionsText()
{
	if(m_searchOptionsText.m_hWnd)
	{
		CString str = "";

		if(m_searchMode == ESM_BY_NAME)
			str += "By Name";
		else if(m_searchMode == ESM_BY_TYPE)
			str += "By Type";
		else //if(m_searchMode == ESM_BY_ASSET)
			str += "By Asset";
		
		if(m_searchResultHandling == ESRH_HIDE_OTHERS)
			str += ", Hide filtered";
		else if(m_searchResultHandling == ESRH_FREEZE_OTHERS)
			str += ", Freeze filtered";
		else if(m_searchResultHandling == ESRH_JUST_SELECT)
			str += ", Just Select";
		
		if(m_bOR)
			str += ", OR";
		else
			str += ", AND";

		m_searchOptionsText.SetWindowText(str);
	}
}

void CViewportTitleDlg::LoadCustomResPresets( const char* keyName, std::vector<CString>& outCustompresets )
{
	// Load custom resolution presets, if any.
	CXTRegistryManager regMgr;
	outCustompresets.resize(MAX_NUM_CUSTOM_RES_PRESETS);
	for(int i=0; i<MAX_NUM_CUSTOM_RES_PRESETS; ++i)
	{
		if( i >= outCustompresets.size() )
			break;
		CString entry;
		entry.Format("%s%d",keyName, i);
		CString res = regMgr.GetProfileString("CustomResPresets", entry, "");
		if(res.IsEmpty())
			break;
		outCustompresets[i] = res;
	}
}

void CViewportTitleDlg::SaveCustomResPresets( const char* keyName, const std::vector<CString>& custompresets )
{
	// Save custom resolution presets, if any.
	CXTRegistryManager regMgr;
	for(size_t i=0; i<custompresets.size(); ++i)
	{
		if( i >= MAX_NUM_CUSTOM_RES_PRESETS )
			break;
		if(custompresets[i].IsEmpty())
			break;
		CString entry;
		entry.Format("%s%d", keyName,i);
		regMgr.WriteProfileString("CustomResPresets", entry, custompresets[i]);
	}
}

void CViewportTitleDlg::UpdateCustomResPresets( const CString& text, std::vector<CString>& custompresets )
{
	std::vector<CString> backup(custompresets);
	custompresets[0] = text;
	for (int k=0, m=1; k<MAX_NUM_CUSTOM_RES_PRESETS && m<MAX_NUM_CUSTOM_RES_PRESETS; ++k)
	{
		if( k >= backup.size() )
			break;
		if (backup[k] != text)
		{
			if( m>= custompresets.size() )
				break;
			custompresets[m++] = backup[k];
		}
	}
}
